package puzzle.model;


import java.util.List;
import java.util.ArrayList;

import java.io.IOException;
import java.io.FileNotFoundException;

import java.io.FileReader;
import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.PrintWriter;


// This is a model class for the Record domain.
public class RecordsModel {
    
    private String moveRecordsFilePath;
    private String timeRecordsFilePath;
    
    private List<Record> moveRecords;
    private List<Record> timeRecords;

    public RecordsModel(String moveRecordsFilePath, String timeRecordsFilePath){
        
        this.moveRecordsFilePath = moveRecordsFilePath;
        this.timeRecordsFilePath = timeRecordsFilePath;
        
        moveRecords = new ArrayList<Record>();
        timeRecords = new ArrayList<Record>();        
        generateRecords();
        
    }    
    
    // Retrieves records from txt files for both move and time records.
    // Stores them in array lists.
    private void generateRecords() {
        
        FileReader fr = null;
        BufferedReader br = null;

        String[] paths = { moveRecordsFilePath, timeRecordsFilePath };
        List[] records = { moveRecords, timeRecords };
        
        try {  
            
            for (int i=0; i<paths.length; i++){
                
                fr = new FileReader(paths[i]);
                br = new BufferedReader(fr);
                
                String line;
                while ( ((line= br.readLine()) != null ) && ( !line.isEmpty() ) ) {
                    String[] elements = line.split(",");
                    Record record = new Record(elements[0], Double.parseDouble(elements[1].trim()));
                    records[i].add(record);
                }
                
            }

        } catch (FileNotFoundException e) {
            System.out.println(e.getMessage());
        } catch (IOException ioe) {
            System.out.println(ioe.getMessage());
        } finally {
            try {
                fr.close();
            } catch (IOException ioe) {
                 System.out.println(ioe.getMessage());
            }
        }
        
    }
    

    // Returns up to 10 best records in a number of moves as na array list.
    public List<Record> getAllMoveRecords() {
        return moveRecords;
    }

    // Returns up to 10 best records in shortest time taken as na array list.
    public List<Record> getAllTimeRecords() {
        return timeRecords;
    }
    
    
    // Clears records lists.
    // Deletes records from txt files.
    public void clearRecords() {
        
        FileWriter fw = null;
        PrintWriter pw = null;

        try {
            
            // Delete existing records in a number of moves.
            fw = new FileWriter(moveRecordsFilePath, false);
            pw = new PrintWriter(fw);
            pw.println();
            
            // Delete existing records in shortest time taken.
            fw = new FileWriter(timeRecordsFilePath, false);
            pw = new PrintWriter(fw);
            pw.println();
            
            // Clear records lists.
            moveRecords.clear();
            timeRecords.clear();
            
        } catch (FileNotFoundException e) {
            System.out.println(e.getMessage());
        } catch (IOException ioe) {
            System.out.println(ioe.getMessage());
        } finally {
            try {
                fw.close();
            } catch (IOException ioe) {
                System.out.println(ioe.getMessage());
            }
        }
        
    }
            

    // Checks for a new record.
    // If there is one adds it to the records lists.
    // Also saves it in a txt file.
    public Record tryRecord(String name, double result, String type) {
        
        List<Record> recordsList;
        String recordsFilePath;
        if(type.equals("move")){
            recordsList = moveRecords;
            recordsFilePath = moveRecordsFilePath;
        } else {
            recordsList = timeRecords;
            recordsFilePath = timeRecordsFilePath;
        }
        
        Record newRecord = checkForNewRecord(name, result, recordsList);
        if (newRecord != null) {
            saveRecord(recordsList, recordsFilePath);
        }
        return newRecord;   
        
    }
    
    
    // Checks for a new record if there is one adds it to the records lists.
    private Record checkForNewRecord(String name, double result, List<Record> recordsList) {
        
        Record newRecord = null;

        // If a result is better than any record in the list add it to the list in a proper place.
        for (Record currentRec : recordsList) {
            if( result <= currentRec.getResult() ) {
                newRecord = new Record(name, result);
                recordsList.add(recordsList.indexOf(currentRec), newRecord);
                if (recordsList.size()>10) {
                    recordsList.remove(10);
                }
                break;
            }
        }
        
        // If a result is not better than any in the list but there are less than 10 records
        // add the new result at the end of the records list.
        if ( newRecord==null && recordsList.size()<10 ) {
            newRecord = new Record(name, result);
            recordsList.add(newRecord);            
        }
        
        return newRecord;
    }
    

    // Saves records in a txt file.
    private void saveRecord(List<Record> recordsList, String recordsFilePath) {

        FileWriter fw = null;
        PrintWriter pw = null;

        try {
            
            // Delete existing records.
            fw = new FileWriter(recordsFilePath, false);
            pw = new PrintWriter(fw);
            pw.println();

            // Append records from a new list.
            fw = new FileWriter(recordsFilePath, true);
            pw = new PrintWriter(fw);
            for (Record currentRec : recordsList) {
                String name = currentRec.getName();
                double moves = currentRec.getResult();
                String nextRecord = name + "," + moves;
                pw.print(nextRecord);
                pw.println();
            }
            
        } catch (FileNotFoundException e) {
            System.out.println(e.getMessage());
        } catch (IOException ioe) {
            System.out.println(ioe.getMessage());
        } finally {
            try {
                fw.close();
            } catch (IOException ioe) {
                System.out.println(ioe.getMessage());
            }
        }
        
    }     
    

}
